package com.hyh.util;

import java.text.DateFormatSymbols;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;

public class DateUtil {

	public static final String DATE_TIME_FORMAT_01 = "yyyy-MM-dd HH:mm:ss";
	public static final String DATE_TIME_FORMAT_02 = "yyyy-MM-dd HH:mm:00";
	public static final String DATE_TIME_FORMAT_03 = "yyyy年MM月dd日 HH时mm分";
	public static final String DATE_TIME_FORMAT_04 = "yyyy-MM-dd HH:mm";
	public static final String DATE_TIME_FORMAT_05 = "yyyyMMddHHmmss";
	public static final String DATE_TIME_FORMAT_06 = "yyyy年MM月dd日 HH时mm分ss秒";
	public static final String DATE_FORMAT_01 = "yyyy-MM-dd";
	public static final String DATE_FORMAT_02 = "yyyy年MM月dd日";
	public static final String DATE_FORMAT_YYYYMMDD = "yyyyMMdd";
	public static final String DATE_FORMAT_YYMMDD = "yyMMdd";

	public static String snPrefix() {
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_FORMAT_YYYYMMDD);
		LocalDateTime now = LocalDateTime.now();
		return now.format(formatter);
	}

	/**
	 * 格式化日期时间
	 * 
	 * @return
	 */
	public static String formatDateTime(Date date) {
		return formatDate(date, DATE_TIME_FORMAT_01);
	}

	/**
	 * 格式化日期
	 * 
	 * @return
	 */
	public static String formatDate(Date date) {
		return formatDate(date, DATE_FORMAT_01);
	}

	/**
	 * 取当前日期时间
	 * 
	 * @return
	 */
	public static String getCurrentDateTime() {
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_TIME_FORMAT_01);
		return LocalDateTime.now().format(formatter);
	}

	/**
	 * 取当前日期
	 * 
	 * @return
	 */
	public static String getCurrentDate() {
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_FORMAT_01);
		return LocalDateTime.now().format(formatter);
	}

	/**
	 * @param startDate
	 *            开始日期时间
	 * @param endDate
	 *            结束日期时间
	 * @return 获取日期天数
	 */
	public static long getDiffDays(Date startDate, Date endDate) {
		try {
			long diff = endDate.getTime() - startDate.getTime();
			long days = diff / (1000 * 60 * 60 * 24);
			return days;
		} catch (Exception e) {
			e.printStackTrace();
		}

		return 0;
	}

	/**
	 * @param startDate
	 *            开始日期时间
	 * @param endDate
	 *            结束日期时间
	 * @return 获取日期天数
	 */
	public static long getDiffDaysForDay(Date startDate, Date endDate) {
		if(startDate == null || endDate == null) return 0;
		LocalDate startDay = dateToLocalDateTime(startDate).toLocalDate();
		LocalDate endDay = dateToLocalDateTime(endDate).toLocalDate();
		return startDay.until(endDay, ChronoUnit.DAYS);
	}

	/**
	 * 获取周几
	 * 
	 * @Title: getWeekDay
	 * @Description: TODO
	 * @author: share 2016年8月15日
	 * @modify: share 2016年8月15日
	 * @return
	 */
	public static String getWeekDay() {
		DateFormatSymbols symboles = new DateFormatSymbols(Locale.getDefault());
		symboles.setShortWeekdays(new String[] { "", "7", "1", "2", "3", "4", "5", "6" });
		SimpleDateFormat date = new SimpleDateFormat("E", symboles);
		return date.format(new Date());
	}

	public static long getDiffDays2(Date startDate, Date endDate) {
		try {

			long diff = endDate.getTime() - startDate.getTime();
			long days = diff / (999 * 60 * 60 * 24);
			return days;
		} catch (Exception e) {
			e.printStackTrace();
		}

		return 0;
	}

	public static Date getPointDate(int weightValue) {
		Calendar clr = Calendar.getInstance();
		clr.setTime(new Date());
		clr.add(Calendar.DATE, weightValue);
		return clr.getTime();
	}

	/**
	 * 字符串yyyy-MM-dd转换到Date类型
	 * 
	 * @param dateStr
	 *            yyyy-MM-dd
	 * @return Date
	 */
	public static Date strDate2Date(String dateStr) {
		return str2Date(dateStr, DATE_FORMAT_01);
	}

	/**
	 * 字符串转换到Date类型
	 * 
	 * @param dateStr
	 *            需要转换的字符串
	 * @param format
	 *            转换格式
	 * @return Date
	 */
	public static Date str2Date(String dateStr, String format) {
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
		LocalDateTime date = LocalDateTime.parse(dateStr, formatter);
		return localDateTimeToDate(date);
	}

	/**
	 * @param dt
	 *            Date日期类型
	 * @param fmtDate
	 *            格式样式，如：yyyy-MM-dd HH:mm:ss
	 * @return 自定义格式
	 */
	public static String formatDate(Date dt, String fmtDate) {
		if (dt != null) {
			DateTimeFormatter formatter = DateTimeFormatter.ofPattern(fmtDate);
			return dateToLocalDateTime(dt).format(formatter);
		}
		return null;
	}

	/**
	 * 时间转日期
	 * 
	 * @param timeStr
	 * @return
	 */
	public static String timeConvertDate(String timeStr) {
		SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT_01);
		dateFormat.setLenient(false);
		Date date = dateFormat.parse(timeStr, new ParsePosition(0));
		return dateFormat.format(date);
	}

	/**
	 * 获取时间段内所有的日期集合
	 * 
	 * @param dBegin
	 * @param dEnd
	 * @return
	 */
	public static List<Date> findDates(Date dBegin, Date dEnd) {
		List<Date> lDate = new ArrayList<Date>();
		lDate.add(dBegin);
		Calendar calBegin = Calendar.getInstance();
		calBegin.setTime(dBegin);
		Calendar calEnd = Calendar.getInstance();
		calEnd.setTime(dEnd);
		while (dEnd.after(calBegin.getTime())) {
			calBegin.add(Calendar.DAY_OF_MONTH, 1);
			lDate.add(calBegin.getTime());
		}
		return lDate;
	}

	/**
	 * 日期加减计算
	 * 
	 * @param date
	 *            日期字符串，格式yyyy_MM_dd
	 * @param day
	 *            正为加负为减
	 * @return 日期字符串
	 */
	public static String dateStrCalculate(String date, int day) {
		Calendar nowCalender = str2Calendar(date, DATE_FORMAT_01);
		nowCalender.add(Calendar.DAY_OF_MONTH, day);
		return formatDate(nowCalender.getTime(), DATE_FORMAT_01);
	}

	/**
	 * 字符串转换到Calendar类型
	 * 
	 * @param dateStr
	 *            需要转换的字符串
	 * @param format
	 *            转换格式
	 * @return Calendar
	 */
	public static Calendar str2Calendar(String dateStr, String format) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(str2Date(dateStr, format));
		return calendar;
	}

	public static String dateCalculate(Date date, int day) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DAY_OF_MONTH, day);
		return formatDate(calendar.getTime(), DATE_FORMAT_01);
	}

	public static Date getTimeByPointParams(Date date, Integer year, Integer month, Integer day, Integer hour,
			Integer minute, Integer second) {
		Calendar calendar = Calendar.getInstance();
		if (date == null) {
			calendar.setTime(new Date());
		} else {
			calendar.setTime(date);
		}
		if (year != null) {
			calendar.set(Calendar.YEAR, year);
		}
		if (month != null) {
			calendar.set(Calendar.MONTH, month - 1);
		}
		if (day != null) {
			calendar.set(Calendar.DAY_OF_MONTH, day);
		}
		if (hour != null) {
			calendar.set(Calendar.HOUR_OF_DAY, hour);
		}
		if (minute != null) {
			calendar.set(Calendar.MINUTE, minute);
		}
		if (second != null) {
			calendar.set(Calendar.SECOND, second);
		}
		return calendar.getTime();
	}

	/**
	 * @param startDate
	 * @param endDate
	 * @return 对比 startDate > endDate 为true 否为false
	 */
	public static boolean compareDate(Date startDate, Date endDate) {
		if (startDate.compareTo(endDate) == 0) {
			return false;
		} else {
			if (startDate.after(endDate)) {
				return true;
			} else {
				return false;
			}
		}
	}

	/**
	 * @param startDate
	 * @param endDate
	 * @return 对比 startDate > endDate 为true 否为false
	 */
	public static boolean compareDate(String startDate, String endDate, String formatDate) {
		Date d1 = null;
		Date d2 = null;
		try {
			d1 = str2Date(startDate, formatDate);
			d2 = str2Date(endDate, formatDate);
			return compareDate(d1, d2);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * @param startDate
	 *            开始日期时间
	 * @param endDate
	 *            结束日期时间
	 * @return 获取日期天数
	 */
	public static long getDiffDay(Date startDate, Date endDate) {
		try {
			LocalDateTime ld1 = dateToLocalDateTime(startDate);
			LocalDateTime ld2 = dateToLocalDateTime(endDate);
			return ld1.until(ld2, ChronoUnit.DAYS);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return 0;
	}

	/**
	 * @param startDate
	 *            开始日期时间
	 * @param endDate
	 *            结束日期时间
	 * @return 获取日期天数
	 */
	public static long getDiffDay(String startDate, String endDate, String formatPattern) {
		try {
			Date start = str2Date(startDate, formatPattern);
			Date end = str2Date(endDate, formatPattern);
			return getDiffDay(start, end);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return 0;
	}

	/**
	 * @param startDate
	 *            开始日期时间
	 * @param endDate
	 *            结束日期时间
	 * @return 获取两个日期时间的秒数差值
	 */
	public static long getDiffSecond(Date startDate, Date endDate) {
		try {
			long diff = endDate.getTime() - startDate.getTime();
			long days = diff / 1000;
			return days;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return 0;
	}

	/**
	 * @param startDate
	 *            开始日期时间
	 * @param endDate
	 *            结束日期时间
	 * @return 获取两个日期时间的秒数差值
	 */
	public static long getDiffSecond(String startDate, String endDate, String formatPattern) {
		SimpleDateFormat sdf = new SimpleDateFormat(formatPattern);
		try {
			Date start = sdf.parse(startDate);
			Date end = sdf.parse(endDate);
			return getDiffSecond(start, end);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return 0;
	}

	public static Date calDateOfSecond(int seconds) {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.SECOND, seconds);
		return cal.getTime();
	}
	
	public static Date calDateOfSecond(Date date, int seconds) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.SECOND, seconds);
		return cal.getTime();
	}
	
	public static String calDateOfSecond(Date date, int seconds, String format) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.SECOND, seconds);
		return formatDate(cal.getTime(), format);
	}
	
	public static String calDateOfSecond(String dateStr, int seconds, String format) {
		Date date = str2Date(dateStr, format);
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.SECOND, seconds);
		return formatDate(cal.getTime(), format);
	}

	public static Date calDateOfMinute(int minutes) {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.MINUTE, minutes);
		return cal.getTime();
	}

	public static Date calDateOfHour(int hours) {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.HOUR_OF_DAY, hours);
		return cal.getTime();
	}

	public static Date calDateOfDay(int days) {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.DAY_OF_MONTH, days);
		return cal.getTime();
	}

	public static Date calDateOfDay(Date date, int days) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.DAY_OF_MONTH, days);
		return cal.getTime();
	}

	public static Date calDateOfMonth(int month) {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.MONTH, month);
		return cal.getTime();
	}

	/**
	 * 功能描述：返回小
	 *
	 * @param date
	 *            日期
	 * @return 返回小时
	 */
	public static int getHour(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.HOUR_OF_DAY);
	}

	/**
	 * 功能描述：返回分
	 *
	 * @param date
	 *            日期
	 * @return 返回分钟
	 */
	public static int getMinute(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.MINUTE);
	}
	
	/**
	 * 功能描述：返回秒
	 *
	 * @param date
	 *            日期
	 * @return 返回秒
	 */
	public static int getSecond(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.SECOND);
	}
	
	/**
	 * 
	 * getWeek:(返回周).
	 *
	 * @author huangyihao
	 * 2017年4月6日 下午3:41:19
	 * @param date
	 * @return 1-7 周日-周六
	 *
	 */
	public static int getWeek(Date date){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.DAY_OF_WEEK);
	}

	public static LocalDateTime dateToLocalDateTime(Date date) {
		if(date == null) return null;
		Instant instant = date.toInstant();
		ZoneId zoneId = ZoneId.systemDefault();
		LocalDateTime localDateTime = instant.atZone(zoneId).toLocalDateTime();
		return localDateTime;
	}
	
	public static Date localDateTimeToDate(LocalDateTime localDateTime) {
		if(localDateTime == null) return null;
		ZoneId zoneId = ZoneId.systemDefault();
		ZonedDateTime zdt = localDateTime.atZone(zoneId);
		Date date = Date.from(zdt.toInstant());
		return date;
	}
	/**
	 * LocalDate转Date
	 * @author wuwang
	 * @param localDate
	 * @return
	 * 2018-6-15:17:53
	 */
	public static String localDateToStr(LocalDate localDate, String format){
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
		return localDate.format(formatter);
	}
	
}
